/*
    PhotoFlip, a free 3d photo managment suite.
    Copyright (C) 2007  Elisée MAURER, Gaétan WALTER
    
    This file is part of PhotoFlip.
    Contact: http://www.photoflip.org/

    PhotoFlip is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PhotoFlip is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PhotoFlip.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "visualisation.hpp"

#include <GL/glu.h>
#include <iostream>
#include <cmath>

visualisation::visualisation(library *lib, bool frames): m_wasInit(false), m_lib(lib),
	m_frames(frames), m_slideshow(false), m_photo(0), m_zoom(0.0f) {
	
}

visualisation::~visualisation() {
	
}

void visualisation::setSelectedTexture(GLuint texture) {
	m_texSelected = texture;
}

void visualisation::renderFloor() {
	//glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 128);
	
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor4ub(0, 0, 0, 192);
	
	glBegin(GL_POLYGON);
		glVertex3d(-500, -500, 0);
		glVertex3d(500, -500, 0);
		glVertex3d(500, 500, 0);
		glVertex3d(-500, 500, 0);
	glEnd();
	
	glDisable(GL_BLEND);
}

void visualisation::renderPhoto(GLuint texPhoto, bool selected) {
	glPushMatrix();
	GLint width, height;
	
	glColor3f(1.0f, 1.0f, 1.0f);
	
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texPhoto);
	
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
	
	float ratio = float(width) / height;
	
	if(ratio > 1.0f) {
		glBegin(GL_QUADS);
			glTexCoord2i(0, 1);
			glVertex3d(-7.5, -7.5 / ratio, 0);
			glTexCoord2i(1, 1);
			glVertex3d(7.5, -7.5 / ratio, 0);
			glTexCoord2i(1, 0);
			glVertex3d(7.5, 7.5 / ratio, 0);
			glTexCoord2i(0, 0);
			glVertex3d(-7.5, 7.5 / ratio, 0);
		glEnd();
	} else {
		glBegin(GL_QUADS);
			glTexCoord2i(0, 1);
			glVertex3d(-5 * ratio, -5, 0);
			glTexCoord2i(1, 1);
			glVertex3d(5 * ratio, -5, 0);
			glTexCoord2i(1, 0);
			glVertex3d(5 * ratio, 5, 0);
			glTexCoord2i(0, 0);
			glVertex3d(-5 * ratio, 5, 0);
		glEnd();
	}
	
	if(selected) {
		glEnable(GL_BLEND);
		glBindTexture(GL_TEXTURE_2D, m_texSelected);
		
		if(ratio > 1.0f) {
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(-7.5 - 0.3, -7.5 / ratio - 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(-7.5 - 0.3 + SELECTED_SIZE, -7.5 / ratio - 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(-7.5 - 0.3 + SELECTED_SIZE, -7.5 / ratio - 0.3 + SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(-7.5 - 0.3, -7.5 / ratio - 0.3 + SELECTED_SIZE, 0.10f);
			glEnd();
			
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(7.5 + 0.3, 7.5 / ratio + 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(7.5 + 0.3 - SELECTED_SIZE, 7.5 / ratio + 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(7.5 + 0.3 - SELECTED_SIZE, 7.5 / ratio + 0.3 - SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(7.5 + 0.3, 7.5 / ratio + 0.3 - SELECTED_SIZE, 0.10f);
			glEnd();
			
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(7.5 + 0.3, -7.5 / ratio - 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(7.5 + 0.3 - SELECTED_SIZE, -7.5 / ratio - 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(7.5 + 0.3 - SELECTED_SIZE, -7.5 / ratio - 0.3 + SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(7.5 + 0.3, -7.5 / ratio - 0.3 + SELECTED_SIZE, 0.10f);
			glEnd();
			
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(-7.5 - 0.3, 7.5 / ratio + 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(-7.5 - 0.3 + SELECTED_SIZE, 7.5 / ratio + 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(-7.5 - 0.3 + SELECTED_SIZE, 7.5 / ratio + 0.3 - SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(-7.5 - 0.3, 7.5 / ratio + 0.3 - SELECTED_SIZE, 0.10f);
			glEnd();
		} else {
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(-5 * ratio - 0.3, -5 - 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(-5 * ratio - 0.3 + SELECTED_SIZE, -5 - 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(-5 * ratio - 0.3 + SELECTED_SIZE, -5 - 0.3 + SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(-5 * ratio - 0.3, -5 - 0.3 + SELECTED_SIZE, 0.10f);
			glEnd();
			
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(5 * ratio + 0.3, 5 + 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(5 * ratio + 0.3 - SELECTED_SIZE, 5 + 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(5 * ratio + 0.3 - SELECTED_SIZE, 5 + 0.3 - SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(5 * ratio + 0.3, 5 + 0.3 - SELECTED_SIZE, 0.10f);
			glEnd();
			
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(5 * ratio + 0.3, -5 - 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(5 * ratio + 0.3 - SELECTED_SIZE, -5 - 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(5 * ratio + 0.3 - SELECTED_SIZE, -5 - 0.3 + SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(5 * ratio + 0.3, -5 - 0.3 + SELECTED_SIZE, 0.10f);
			glEnd();
			
			glBegin(GL_QUADS);
				glTexCoord2i(0, 1);
				glVertex3d(-5 * ratio - 0.3, 5 + 0.3, 0.10f);
				glTexCoord2i(1, 1);
				glVertex3d(-5 * ratio - 0.3 + SELECTED_SIZE, 5 + 0.3, 0.10f);
				glTexCoord2i(1, 0);
				glVertex3d(-5 * ratio - 0.3 + SELECTED_SIZE, 5 + 0.3 - SELECTED_SIZE, 0.10f);
				glTexCoord2i(0, 0);
				glVertex3d(-5 * ratio - 0.3, 5 + 0.3 - SELECTED_SIZE, 0.10f);
			glEnd();
		}
	}
	
	glDisable(GL_TEXTURE_2D);
	
	glPopMatrix();
}

void visualisation::renderFrame(GLuint texFrame) {
	glEnable(GL_BLEND);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texFrame);
	
	GLint frameWidth, frameHeight;
	
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &frameWidth);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &frameHeight);
	
	glBegin(GL_QUADS);
		glTexCoord2i(0, 1);
		glVertex3d(-frameWidth / 80.0f, -frameHeight / 80.0f, 0.05f);
		glTexCoord2i(1, 1);
		glVertex3d(frameWidth / 80.0f, -frameHeight / 80.0f, 0.05f);
		glTexCoord2i(1, 0);
		glVertex3d(frameWidth / 80.0f, frameHeight / 80.0f, 0.05f);
		glTexCoord2i(0, 0);
		glVertex3d(-frameWidth / 80.0f, frameHeight / 80.0f, 0.05f);
	glEnd();

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);
}

void visualisation::initScene() {
	m_wasInit = true;
}

void visualisation::showFrames(bool state) {
	m_frames = state;
}

void visualisation::setZoom(float zoom) {
	m_zoom = zoom;
}

float visualisation::getZoom() {
	return m_zoom;
}

void visualisation::moveTo(int photo) {
	if(m_lib->getCollectionPhotos().size() > 0)
		photo = photo % int(m_lib->getCollectionPhotos().size());
	if(photo < 0) photo += m_lib->getCollectionPhotos().size();
	m_photo = photo;
}

void visualisation::slideshow(bool state) {
	m_slideshow = state;
}

// ----------------------------------------------------------------------------
// visuCircular
// ----------------------------------------------------------------------------
visuCircular::visuCircular(library *lib, bool frames): visualisation(lib, frames), m_angle(0.0f), m_targetZoom(0.0f) {
	
}

visuCircular::~visuCircular() {
	
}

void visuCircular::initScene() {
	visualisation::initScene();
	
	/*glEnable(GL_LIGHTING);
	
	GLfloat global_ambient[] = { 0.2f, 0.2f, 0.2f, 0.0f };
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
	
	glShadeModel(GL_SMOOTH);
	
	glEnable(GL_LIGHT0);
	
	GLfloat light0[] = { 0.5f, 0.5f, 0.5f };
	GLfloat light0spe[] = { 1.0f, 1.0f, 1.0f };
	GLfloat light0pos[] = { 0.0f, 0.0f, 80.f };
	GLfloat light0dir[] = { 0.0f, 0.0f, -1.0f };
	glLightfv(GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, light0);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light0spe);
	glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 10);
	glLightfv(GL_LIGHT0, GL_POSITION, light0pos);
	glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0dir);
	
	//glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.02f);*/
}

bool visuCircular::updateScene() {
	bool next = false;
	
	// zoom
	if(m_zoom + fabs(m_targetZoom - m_zoom) / 5 + 0.1f < m_targetZoom) {
		m_zoom += fabs(m_targetZoom - m_zoom) / 5;
		
		next = true;
	} else if(m_zoom - fabs(m_targetZoom - m_zoom) / 5 - 0.1f > m_targetZoom) {
		m_zoom -= fabs(m_targetZoom - m_zoom) / 5;
		next = true;
	} else
		m_zoom = m_targetZoom;
	
	// photo
	float targetAngle = float(m_photo) / m_lib->getCollectionPhotos().size() * 360;
	
	if(m_angle + fabs(targetAngle - m_angle) / 10 + 0.1f < targetAngle) {
		if(targetAngle - m_angle < m_angle - (targetAngle - 360)) {
			m_angle += fabs(targetAngle - m_angle) / 10;
			next = true;
		} else {
			m_angle -= fabs(targetAngle - 360 - m_angle) / 10;
			if(m_angle - 1.0f < targetAngle - 360)
				m_angle += 360.0f;
			next = true;
		}
	} else if(m_angle - fabs(targetAngle - m_angle) / 10 - 0.1f > targetAngle) {
		if(m_angle - targetAngle < (targetAngle + 360) - m_angle) {
			m_angle -= fabs(targetAngle - m_angle) / 10;
			next = true;
		} else {
			m_angle += fabs(targetAngle + 360 - m_angle) / 10;
			if(m_angle + 1.0f > targetAngle + 360)
				m_angle -= 360.0f;
			next = true;
		}
	} else m_angle = targetAngle;
	
	return next;
}

void visuCircular::renderScene() {
	if(!m_wasInit) initScene();
	
	/*glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);*/
	
	glTranslatef(0, 5 - 5 * (m_zoom / 100), (m_zoom / 2) - 50.0f);
	glRotated(10 - 10 * (m_zoom / 100), 1, 0, 0);
	
	for(unsigned int i = 0; i < m_lib->getCollectionPhotos().size(); i++) {
		glPushMatrix();
			glTranslated(0, -12, 0);
			glScaled(1, -1, 1);
			glTranslatef(cos((m_angle - float(i) / m_lib->getCollectionPhotos().size() * 360 + 90) * PI / 180) * 40, 0, sin((m_angle - float(i) / m_lib->getCollectionPhotos().size() * 360+ 90) * PI / 180) * 40);
			glTranslatef(0, 0, -49);
			if(m_lib->getCollectionPhotos()[i].hasTexture) renderPhoto(m_lib->getCollectionPhotos()[i].texPhoto, m_lib->getCollectionPhotos()[i].selected);
			else renderPhoto(m_lib->getErrorTexture(), m_lib->getCollectionPhotos()[i].selected);
			
			if(m_frames) if(m_lib->getCollectionPhotos()[i].hasFrame) renderFrame(m_lib->getCollectionPhotos()[i].texFrame);
		glPopMatrix();
	}
	
	glPushMatrix();
		glTranslatef(0, -6, 0);
		glRotatef(90, 1, 0, 0);
		renderFloor();
	glPopMatrix();
	
	for(unsigned int i = 0; i < m_lib->getCollectionPhotos().size(); i++) {
		glPushMatrix();
			glTranslatef(cos((m_angle - float(i) / m_lib->getCollectionPhotos().size() * 360 + 90) * PI / 180) * 40, 0, sin((m_angle - float(i) / m_lib->getCollectionPhotos().size() * 360+ 90) * PI / 180) * 40);
			glTranslatef(0, 0, -49);
			glLoadName(1 + i);
			
			if(m_lib->getCollectionPhotos()[i].hasTexture) renderPhoto(m_lib->getCollectionPhotos()[i].texPhoto, m_lib->getCollectionPhotos()[i].selected);
			else renderPhoto(m_lib->getErrorTexture(), m_lib->getCollectionPhotos()[i].selected);
			
			if(m_frames) if(m_lib->getCollectionPhotos()[i].hasFrame) renderFrame(m_lib->getCollectionPhotos()[i].texFrame);
		glPopMatrix();
	}
}

void visuCircular::setZoom(float targetZoom) {
	m_targetZoom = targetZoom;
}

float visuCircular::getZoom() {
	return m_targetZoom;
}

// ---------------------------------------------------------------------------
// visuStrew
// ---------------------------------------------------------------------------
visuStrew::visuStrew(library *lib, bool frames): visualisation(lib, frames), m_x(0.0f), m_y(0.0f), m_angleShift(0.0f), m_targetZoom(0.0f) {
	
}

visuStrew::~visuStrew() {
	
}

void visuStrew::initScene() {
	visualisation::initScene();
	
	m_angleShift = 10.0f * rand() / RAND_MAX;
}

bool visuStrew::updateScene() {
	bool next = false;
	
	// zoom
	if(m_zoom + fabs(m_targetZoom - m_zoom) / 5 + 0.1f < m_targetZoom) {
		m_zoom += fabs(m_targetZoom - m_zoom) / 5;
		
		next = true;
	} else if(m_zoom - fabs(m_targetZoom - m_zoom) / 5 - 0.1f > m_targetZoom) {
		m_zoom -= fabs(m_targetZoom - m_zoom) / 5;
		next = true;
	} else
		m_zoom = m_targetZoom;
	
	// photo
	int quad = int(sqrt(m_lib->getCollectionPhotos().size()) + 1);

	float targetX;
	if((m_photo / quad) % 2 == 0)
		targetX = (float(quad - 1) / 2 * 20 - (m_photo % quad) * 20) * (m_targetZoom / 100);
	else
		targetX = (float(quad - 1) / 2 * 20 - (quad - 1 - m_photo % quad) * 20) * (m_targetZoom / 100);
	
	float targetY = -(float(quad - 1) / 2 * 20 - (m_photo / quad) * 20) * (m_zoom / 100);
	
	if(m_x + fabs(targetX - m_x) / 5 + 0.1f < targetX) { m_x += fabs(targetX - m_x) / 5; next = true; }
	else if(m_x - fabs(targetX - m_x) / 5 - 0.1f > targetX) { m_x -= fabs(targetX - m_x) / 5; next = true; }
	else m_x = targetX;
	
	if(m_y + fabs(targetY - m_y) / 5 + 0.1f < targetY) { m_y += fabs(targetY - m_y) / 5; next = true; }
	else if(m_y - fabs(targetY - m_y) / 5 - 0.1f > targetY) { m_y -= fabs(targetY - m_y) / 5; next = true; }
	else m_y = targetY;
	
	return next;
}

void visuStrew::renderScene() {
	if(!m_wasInit) initScene();
	
	// set up camera
	glTranslatef(m_x, m_y, -60 + m_zoom / 2);
	glRotatef(-45 * ((100 - m_zoom) / 100), 1, 0, 0);
	
	glPushMatrix();
		glTranslatef(0, 0, -1.0f);
		renderFloor();
	glPopMatrix();
	
	int quad = int(sqrt(m_lib->getCollectionPhotos().size()) + 1);
	float photoX, photoY;
	for(unsigned int i = 0; i < m_lib->getCollectionPhotos().size(); i++) {
		glPushMatrix();
			if((i/ quad) % 2 == 0)
				photoX = -float(quad - 1) / 2 * 20 + (i % quad) * 20;
			else
				photoX = -float(quad - 1) / 2 * 20 + (quad - 1 - i % quad) * 20;
			
			photoY = float(quad - 1) / 2 * 20 - (i / quad) * 20;
			
			glTranslatef(photoX, photoY, 0);
			if((i % 3) == 0) glRotatef(m_angleShift, 0, 0, 1);
			else if((i % 3) == 1) glRotatef(-m_angleShift, 0, 0, 1);
			
			glLoadName(1 + i);
			if(m_lib->getCollectionPhotos()[i].hasTexture) renderPhoto(m_lib->getCollectionPhotos()[i].texPhoto, m_lib->getCollectionPhotos()[i].selected);
			else renderPhoto(m_lib->getErrorTexture(), m_lib->getCollectionPhotos()[i].selected);
			
			if(m_frames) if(m_lib->getCollectionPhotos()[i].hasFrame) renderFrame(m_lib->getCollectionPhotos()[i].texFrame);
		glPopMatrix();
	}
}

void visuStrew::setZoom(float targetZoom) {
	m_targetZoom = targetZoom;
}

float visuStrew::getZoom() {
	return m_targetZoom;
}

// ---------------------------------------------------------------------------
// visuFold
// ---------------------------------------------------------------------------
visuFold::visuFold(library *lib, bool frames): visualisation(lib, frames), m_angle(0.0f), m_targetZoom(0.0f) {
	
}

visuFold::~visuFold() {
	
}

void visuFold::initScene() {
	visualisation::initScene();
}

bool visuFold::updateScene() {
	bool next = false;
	
	// zoom
	if(m_zoom + fabs(m_targetZoom - m_zoom) / 5 + 0.1f < m_targetZoom) {
		m_zoom += fabs(m_targetZoom - m_zoom) / 5;
		
		next = true;
	} else if(m_zoom - fabs(m_targetZoom - m_zoom) / 5 - 0.1f > m_targetZoom) {
		m_zoom -= fabs(m_targetZoom - m_zoom) / 5;
		next = true;
	} else
		m_zoom = m_targetZoom;
	
	// photo
	float targetAngle = float(m_photo) / m_lib->getCollectionPhotos().size() * 360;
	
	if(m_angle + fabs(targetAngle - m_angle) / 10 + 0.1f < targetAngle) {
		if(targetAngle - m_angle < m_angle - (targetAngle - 360)) {
			m_angle += fabs(targetAngle - m_angle) / 10;
			next = true;
		} else {
			m_angle -= fabs(targetAngle - 360/*à voir*/ - m_angle) / 10;
			if(m_angle - 1.0f < targetAngle - 360)
				m_angle += 360.0f;
			next = true;
		}
	} else if(m_angle - fabs(targetAngle - m_angle) / 10 - 0.1f > targetAngle) {
		if(m_angle - targetAngle < (targetAngle + 360) - m_angle) {
			m_angle -= fabs(targetAngle - m_angle) / 10;
			next = true;
		} else {
			m_angle += fabs(targetAngle + 360 - m_angle) / 10;
			if(m_angle + 1.0f > targetAngle + 360)
				m_angle -= 360.0f;
			next = true;
		}
	} else m_angle = targetAngle;
		
	return next;
}

void visuFold::renderScene() {
	if(!m_wasInit) initScene();
	
	// set up camera
	glTranslatef(0, 0, -60 + m_zoom / 2);
	//glRotatef(-45 * ((100 - m_zoom) / 100), 1, 0, 0);
	
	glPushMatrix();
		glTranslatef(0, 0, -1.0f);
		renderFloor();
	glPopMatrix();
	
	int dist = 0;
	for(unsigned int i = 0; i < m_lib->getCollectionPhotos().size(); i++) {
		/*if(dist > i - (m_lib->getCollectionPhotos().size() - m_photo)) dist = i - (m_lib->getCollectionPhotos().size() - m_photo);*/
		
		glPushMatrix();
			glTranslatef(cos((m_angle - float(i) / m_lib->getCollectionPhotos().size() * 360 + 90) * PI / 180) * (30 + 10 * m_zoom / 100), sin((m_angle - float(i) / m_lib->getCollectionPhotos().size() * 360 + 90) * PI / 180) * (30 + 10 * m_zoom / 100), 0);
			glTranslatef(0, -40 * m_zoom / 100, 0);
			glScalef(1 - 0.5 * float(dist) / m_lib->getCollectionPhotos().size(),
				1 - 0.5 * float(dist) / m_lib->getCollectionPhotos().size(),
				1 - 0.5 * float(dist) / m_lib->getCollectionPhotos().size());
			
			glLoadName(1 + i);
			if(m_lib->getCollectionPhotos()[i].hasTexture) renderPhoto(m_lib->getCollectionPhotos()[i].texPhoto, m_lib->getCollectionPhotos()[i].selected);
			else renderPhoto(m_lib->getErrorTexture(), m_lib->getCollectionPhotos()[i].selected);
			
			if(m_frames) if(m_lib->getCollectionPhotos()[i].hasFrame) renderFrame(m_lib->getCollectionPhotos()[i].texFrame);
		glPopMatrix();
	}
}

void visuFold::setZoom(float targetZoom) {
	m_targetZoom = targetZoom;
}

float visuFold::getZoom() {
	return m_targetZoom;
}
